package com.haojiang.mh.widget.chart;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.haojiang.mh.R;
import com.haojiang.mh.service.entity.DayScoreBean;
import com.haojiang.mh.utils.MUtil;
import com.haojiang.mh.utils.SizeUtil;
import com.haojiang.mh.widget.OnScoreBallClickListener;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 睡眠评分日历View
 * 当前用在月报
 */
public class SleepEvaluateCalendarView extends ViewGroup {

    private final int DEFAULT_DAYS_IN_WEEK = 7;//默认一周7天
    private int defaultRows = 6;//一个月的周数
    //行之间间距、间隔线左右定点到左右边的间距、间隔线高度
    private int paddingOfRow, paddingOfLR, intervalLineHeight;//间距
    //默认每天宽度、默认每天高度、默认一周文本（Mon、Tue ...）高度
    private int defaultItemWidth, defaultItemHeight, defaultWeekHeight;
    //间隔线、工作日、周末 颜色值
    private int intervalLineColor, weekDayColor, weekendColor;
    private int weekDaySize;//一周文本字体大小（Mon、Tue ...）
    private String[] weekDays;//一周文本
    private AttributeSet attrs;//通用在DayTextView的AttributeSet
    private int defStyleAttr;
    private String bestScoreDate;//最高得分日
    private List<DayScoreBean> beanList;//数据集

    private OnScoreBallClickListener mOnScoreBallClickListener;

    public SleepEvaluateCalendarView(Context context) {
        this(context, null);
    }


    public SleepEvaluateCalendarView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SleepEvaluateCalendarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.attrs = attrs;
        this.defStyleAttr = defStyleAttr;

        @SuppressLint("CustomViewStyleable")
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SleepEvaluateCalendar, defStyleAttr, 0);
        intervalLineColor = a.getColor(R.styleable.SleepEvaluateCalendar_interval_color, getResources().getColor(R.color.white) & 0x19FFFFFF);
        intervalLineHeight = a.getDimensionPixelOffset(R.styleable.SleepEvaluateCalendar_interval_height, SizeUtil.dp2px(context, 0.5f));
        weekDayColor = a.getColor(R.styleable.SleepEvaluateCalendar_week_day_color, getResources().getColor(R.color.white_half));
        weekDaySize = a.getDimensionPixelSize(R.styleable.SleepEvaluateCalendar_week_day_size, 14);
        a.recycle();

//        weekendColor = getResources().getColor(R.color.purple_3);
        weekendColor = getResources().getColor(R.color.color_golden_dark_n);
        weekDays = getResources().getStringArray(R.array.weekDayArray);
        paddingOfRow = SizeUtil.dp2px(context, 5);
        paddingOfLR = SizeUtil.dp2px(context, 10);
        defaultItemWidth = SizeUtil.dp2px(getContext(), 48);
        defaultItemHeight = SizeUtil.dp2px(getContext(), 67);
        defaultWeekHeight = SizeUtil.dp2px(getContext(), 40);

        beanList = new ArrayList<>();
        createDefaultData();
        initAddView();
    }

    public void setOnScoreBallClickListener(OnScoreBallClickListener onScoreBallClickListener) {
        mOnScoreBallClickListener = onScoreBallClickListener;
    }

    /**
     * 初始化随机数据
     */
    private void createDefaultData() {
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        cal.set(year, month - 1, 1);
        int firstDayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        for (int i = 1; i <= MUtil.INSTANCE.getDaysOfMonth(year, month); i++) {
            DayScoreBean bean = new DayScoreBean();
            bean.setDate(String.format(Locale.getDefault(), "%04d-%02d-%02d", year, month, i));
            int dayIndex = (i - 1) % 7 + firstDayOfWeek;
            while (dayIndex > 7) dayIndex -= 7;
            bean.setWeekend(dayIndex == 1 || dayIndex == 7);
            beanList.add(bean);
        }
        getCompleteMonthData();
    }

    /**
     * 初始化
     */
    private void initAddView() {
        defaultRows = beanList.size() / 7;
        for (int i = 0; i < 7; i++) {
            TextView tv = new TextView(getContext());
            tv.setText(weekDays[i]);
            tv.setTextColor((i == 0 || i == 6) ? weekendColor : weekDayColor);
            tv.setTextSize(weekDaySize);
            tv.setGravity(Gravity.CENTER);
            addView(tv);
        }
        for (int i = 0; i < beanList.size(); i++) {
            if (i % 7 == 0 || i % 7 == 6) {
                beanList.get(i).setWeekend(true);
            }
            if (beanList.get(i).getDate().equals(bestScoreDate)) {
                beanList.get(i).setBestScore(true);
            }
            DayTextView dtv = new DayTextView(getContext(), attrs, defStyleAttr);
            if (mOnScoreBallClickListener != null) {
                dtv.setOnScoreBallClickListener(mOnScoreBallClickListener);
            }
            dtv.setDayAndScore(beanList.get(i));
            addView(dtv);
            if ((i + 1) % 7 == 0) {
                View v = new View(getContext());
                v.setBackgroundColor(intervalLineColor);
                addView(v);
            }
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int count = getChildCount();
        final int parentLeft = 0;
        int childTop = 0, childLeft = parentLeft, periodNum = 0;
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            final int width = child.getMeasuredWidth();
            final int height = child.getMeasuredHeight();
            if (child instanceof TextView) {//周几文本（Sun、Mon...）
                child.layout(childLeft, childTop, childLeft + width, childTop + height);
                childLeft += width;
                if (periodNum % DEFAULT_DAYS_IN_WEEK == (DEFAULT_DAYS_IN_WEEK - 1)) {
                    childLeft = parentLeft;
                    childTop += height;
                }
                periodNum++;
            } else if (child instanceof DayTextView) {//每天
                child.layout(childLeft, childTop, childLeft + width, childTop + height);
                childLeft += width;
                if (periodNum % DEFAULT_DAYS_IN_WEEK == (DEFAULT_DAYS_IN_WEEK - 1)) {
                    childLeft = parentLeft;
                    childTop += height;
                }
                periodNum++;
            } else {//间隔线
                child.layout(
                        childLeft + paddingOfLR,
                        childTop + paddingOfRow,
                        childLeft + width - paddingOfLR,
                        childTop + height + paddingOfRow
                );
                childTop += paddingOfRow * 2 + intervalLineHeight;
            }
        }
    }

    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
        int specWidthSize = MeasureSpec.getSize(widthMeasureSpec);
        int specWidthMode = MeasureSpec.getMode(widthMeasureSpec);
        int specHeightSize = MeasureSpec.getSize(heightMeasureSpec);
        int specHeightMode = MeasureSpec.getMode(heightMeasureSpec);

        if (specHeightMode == MeasureSpec.UNSPECIFIED || specWidthMode == MeasureSpec.UNSPECIFIED) {
            if (specWidthMode == MeasureSpec.UNSPECIFIED) {
                specWidthSize = defaultItemWidth * 7;
            }
            if (specHeightMode == MeasureSpec.UNSPECIFIED) {
                specHeightSize = defaultItemHeight * defaultRows + defaultWeekHeight;
            }
        }

        final int measureTileWidth = specWidthSize / DEFAULT_DAYS_IN_WEEK;//日历中每天item的宽
        final int measureTileHeight = (specHeightSize - defaultWeekHeight) / defaultRows;//日历中每天item的高

        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            int childWidthMeasureSpec, childHeightMeasureSpec;
            if (child instanceof TextView) {//周几文本（Sun、Mon...）
                childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(measureTileWidth, MeasureSpec.EXACTLY);
                childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(defaultWeekHeight, MeasureSpec.EXACTLY);
            } else if (child instanceof DayTextView) {//每天
                childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(measureTileWidth, MeasureSpec.EXACTLY);
                childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(measureTileHeight, MeasureSpec.EXACTLY);
            } else {//间隔线
                childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(specWidthSize, MeasureSpec.AT_MOST);
                childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(intervalLineHeight, MeasureSpec.AT_MOST);
            }
            child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
        }

        int intervalHeight = paddingOfRow * 2 + intervalLineHeight;
        setMeasuredDimension(specWidthSize, specHeightSize + intervalHeight * (defaultRows - 1));
    }

    public void setIntervalLineColor(int intervalLineColor) {
        this.intervalLineColor = intervalLineColor;
    }

    public void setIntervalLineHeight(int intervalLineHeight) {
        this.intervalLineHeight = intervalLineHeight;
    }

    public void setPaddingOfRow(int paddingOfRow) {
        this.paddingOfRow = paddingOfRow;
    }

    public void setPaddingOfLR(int paddingOfLR) {
        this.paddingOfLR = paddingOfLR;
    }

    /**
     * 更新数据集
     *
     * @param data     得分数据集
     * @param bestDate 最高得分日
     */
    public void setDateAndData(List<DayScoreBean> data, String bestDate) {
        this.bestScoreDate = bestDate;
        if (beanList == null) beanList = new ArrayList<>();
        beanList.clear();
        if (data != null && !data.isEmpty()) {
            beanList.addAll(data);
            getCompleteMonthData();
        } else {
            createDefaultData();
        }
        removeAllViews();
        initAddView();
        invalidate();
    }

    /**
     * 获取完整月份数据集
     */
    private void getCompleteMonthData() {
        int[] ymd = MUtil.INSTANCE.getYearMonthDay(beanList.get(0).getDate());
        Calendar cal = Calendar.getInstance();
        cal.set(ymd[0], ymd[1] - 1, ymd[2]);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
        while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
            addBeanList(simpleDateFormat.format(new Date(cal.getTimeInMillis())), true);
        }
        cal.set(ymd[0], ymd[1], ymd[2]);
        while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
            addBeanList(simpleDateFormat.format(new Date(cal.getTimeInMillis())), false);
            cal.add(Calendar.DAY_OF_MONTH, 1);
        }
    }

    /**
     * 添加数据集
     */
    private void addBeanList(String date, boolean isBefore) {
        DayScoreBean bean = new DayScoreBean();
        bean.setDate(date);
        bean.setCurrMonth(false);
        if (isBefore) {
            beanList.add(0, bean);
        } else {
            beanList.add(bean);
        }
    }
}
